package login

import (
	"encoding/json"
	"fmt"
	"gitee.com/go-web-2/business/config"
	"gitee.com/go-web-2/business/errors/session_errors"
	"gitee.com/go-web-2/business/route"
	"gitee.com/go-web-2/business/user"
	"gitee.com/go-web-2/orm_framework/sql/querior/selector"
	"gitee.com/go-web-2/web_framework/context"
	errors2 "gitee.com/go-web-2/web_framework/errors"
	"gitee.com/go-web-2/web_framework/middleware"
	"gitee.com/go-web-2/web_framework/session"
	"github.com/google/uuid"
	"io"
	"log"
)

func isLogin(ctx *context.Context) bool {
	sess, err := config.MG.GetSession(ctx)
	if err != nil {
		log.Println(err)
		return false
	}
	err = config.MG.RefreshSession(ctx, sess.ID())
	if err != nil {
		log.Println("refresh session error: ", err)
	}
	return true
}

// ValidateLogin 单机登录校验
func ValidateLogin(next middleware.HandleFunc) middleware.HandleFunc {
	return func(ctx *context.Context) {
		path := ctx.R.URL.Path
		if path == route.FilePreview {
			next(ctx)
			return
		}

		ok := isLogin(ctx)
		if path == route.UserLogin || path == route.UserLogout {
			next(ctx)
			return
		}

		if !ok {
			ctx.RespUnauthorizedDirect(session_errors.SessionNotFound.Error())
			return
		}

		next(ctx)
	}
}

type loginReq struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

func Login(c *context.Context) {
	body, err := io.ReadAll(c.R.Body)
	defer c.R.Body.Close()
	if err != nil {
		log.Println(err)
		c.RespBadRequest(errors2.BadRequestError.Error())
		return
	}
	req := &loginReq{}
	err = json.Unmarshal(body, req)
	if err != nil {
		log.Println(err)
		c.RespBadRequest(errors2.BadRequestError.Error())
		return
	}
	username := req.Username
	password := req.Password

	u := &user.User{}
	// select * from user where username=? and password=?
	res := selector.NewSelector[user.User](config.DB).Where(user.UserUsernameEq(username), user.UserPasswordEq(password)).Get(c.R.Context(), u)
	if res.Err != nil {
		log.Println(res.Err)
		c.RespUnauthorized(session_errors.SessionError.Error())
		return
	}

	sid := uuid.New().String()
	var sess session.Session
	sess, err = config.MG.InitSession(c, sid)
	if err != nil {
		log.Println(err)
		c.RespSystemErr(session_errors.SessionNotFound.Error())
		return
	}

	sessionUser := &user.SessionUser{
		Username: u.Username,
		Address:  u.Address,
		Name:     u.Name,
		Phone:    u.Phone,
		Email:    u.Email,
		Id:       u.Id,
		Avatar:   u.Avatar,
	}
	var bs []byte
	bs, err = json.Marshal(sessionUser)
	if err != nil {
		log.Println(err)
		c.RespSystemErr(errors2.ServerError.Error())
		return
	}
	err = sess.Set(c, sess.ID(), bs)
	if err != nil {
		log.Println(err)
		c.RespSystemErr(errors2.ServerError.Error())
		return
	}
	c.RespOk("登录成功")

}

func OutLogin(c *context.Context) {
	sess, err := config.MG.GetSession(c)
	if err != nil {
		log.Println(err)
		c.RespSystemErr(session_errors.SessionNotFound.Error())
		return
	}
	err = config.MG.RemoveSession(c, sess.ID())
	if err != nil {
		fmt.Println("remove session error", err)
	}
	c.RespOk("登出成功")
}
